﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace Smash
{
    public class FakeVideoServer
    {
        public int Port
        {
            get
            {
                return port_;
            }
        }

        public bool Running
        {
            get;
            set;
        }

        public FakeVideoServer(IPAddress ip, int port)
        {
            ip_ = ip;
            port_ = port;
            fake_server_thread = new Thread(FakeServerHelper);
            fake_server_thread.Start();
        }

        private void FakeServerHelper()
        {
            Running = true;
            try
            {
                byte[] image1, image2;
                FileStream FS = File.Open("rawr640.jpg", FileMode.Open);
                image1 = new byte[FS.Length];
                FS.Read(image1, 0, image1.Length);
                FS.Close();
                FS = File.Open("rawr640-1.jpg", FileMode.Open);
                image2 = new byte[FS.Length];
                FS.Read(image2, 0, image2.Length);
                FS.Close();
                Socket sock = new Socket(AddressFamily.InterNetwork,
                                         SocketType.Dgram,
                                         ProtocolType.Udp);
                EndPoint endPoint = new IPEndPoint(ip_,
                                                   Port);
                byte[] buffer = null;
                int i = 0;
                int sent_sec = 0;
                int image_sec = 0;
                int packet_sec = 0;
                int write_sec = 0;
                ushort handle = 0;
                DateTime started = DateTime.Now;
                while (true)
                {
                    Thread.Sleep(33);
                    if (i == 0)
                    {
                        buffer = image1;
                    }
                    else
                    {
                        i = -1;
                        buffer = image2;
                    }
                    byte count = (byte)(buffer.Length / 1024);
                    if (buffer.Length % 1024 > 0)
                    {
                        ++count;
                    }
                    ushort image_data_to_send = (ushort)buffer.Length;
                    ushort image_data_offset = 0;
                    ushort size = 1024;
                    byte[] packet = new byte[1032];
                    Array.Copy(BitConverter.GetBytes((ushort)IPAddress.HostToNetworkOrder((short)count)), 0, packet, 2, sizeof(ushort));
                    Array.Copy(BitConverter.GetBytes((ushort)IPAddress.HostToNetworkOrder((short)handle++)), 0, packet, 4, sizeof(ushort));
                    for (ushort j = 0; j < count; ++j)
                    {
                        int to_send = 1032;
                        if (image_data_to_send - image_data_offset < size)
                        {
                            size = (ushort)(image_data_to_send - image_data_offset);
                        }
                        Array.Copy(BitConverter.GetBytes((ushort)IPAddress.HostToNetworkOrder((short)j)), 0, packet, 0, sizeof(ushort));
                        Array.Copy(BitConverter.GetBytes((ushort)IPAddress.HostToNetworkOrder((short)size)), 0, packet, 6, sizeof(ushort));
                        Array.Copy(buffer, image_data_offset, packet, 8, size);
                        image_data_offset += size;
                        int offset = 0;
                        ++packet_sec;
                        while (to_send > 0)
                        {
                            ++write_sec;
                            int sent = sock.SendTo(packet, offset, to_send, SocketFlags.None, endPoint);
                            sent_sec += sent;
                            to_send -= sent;
                            offset += sent;
                        }
                    }
                    ++image_sec;
                    if ((DateTime.Now - started).TotalMilliseconds >= 1000.0)
                    {
                        Console.WriteLine("data sent: images {1} packets "
                                          + "{2} bytes {0}",
                                          sent_sec,
                                          image_sec,
                                          packet_sec);
                        if (packet_sec != write_sec)
                        {
                            Console.WriteLine("packet_sec != write_sec",
                                              packet_sec, write_sec);
                        }
                        sent_sec = 0;
                        image_sec = 0;
                        packet_sec = 0;
                        write_sec = 0;
                        started = DateTime.Now;
                    }
                    ++i;
                }
            }
            catch (Exception ex)
            {
            }
        }

        private int port_;
        private IPAddress ip_;
        private Thread fake_server_thread;
    }
}
